from datetime import datetime, timedelta, timezone
from typing import Any
import jwt
from passlib.context import CryptContext
from app.core.config import settings
ALGORITHM = "HS256"
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


def create_access_token(subject: str | Any, expires_delta: timedelta) -> str:
    """
    生成一个JWT访问令牌。
    
    Args:
        subject (str | Any): 令牌的主题，通常是用户ID或其他唯一标识符。
        expires_delta (timedelta): 令牌的有效期时间差。
    
    Returns:
        str: 编码后的JWT令牌字符串。
    
    Notes:
        - 令牌的有效期由当前时间加上`expires_delta`计算得出。
        - 令牌的负载包含`exp`（过期时间）和`sub`（主题）字段。
        - 使用项目的`SECRET_KEY`和指定的`ALGORITHM`进行编码。
    """
    expire = datetime.now(timezone.utc) + expires_delta
    to_encode = {"exp": expire, "sub": str(subject)}
    encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """
    验证用户输入的明文密码与数据库中存储的哈希密码是否匹配。
    
    Args:
        plain_password (str): 用户输入的明文密码。
        hashed_password (str): 数据库中存储的哈希密码。
    
    Returns:
        bool: 如果密码匹配返回 True，否则返回 False。
    """
    return pwd_context.verify(plain_password, hashed_password)


def get_password_hash(password: str) -> str:
    """
    生成密码的哈希值。
    
    Args:
        password (str): 需要哈希的原始密码字符串。
    
    Returns:
        str: 返回密码的哈希值，用于安全存储或验证。
    
    Note:
        使用 `pwd_context.hash` 方法生成哈希值，确保密码的安全性。
    """
    return pwd_context.hash(password)
